package ch.bfh.abcmmh.controller.operating.vehiclepool;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import java.util.Random;

import org.apache.log4j.Logger;

import ch.bfh.abcmmh.controller.logging.TSLoggingFactory;
import ch.bfh.abcmmh.controller.operating.clock.Clock;
import ch.bfh.abcmmh.model.cars.Vehicle;
import ch.bfh.abcmmh.model.cars.specialVehicles.Bus;
import ch.bfh.abcmmh.model.cars.specialVehicles.Car;
import ch.bfh.abcmmh.model.cars.specialVehicles.Truck;
import ch.bfh.abcmmh.model.interfaces.IVehiclePool;
import ch.bfh.abcmmh.model.street.Street;

public class VehiclePool extends Observable implements Observer, IVehiclePool {
	
	Logger logger = TSLoggingFactory.getFileLogger("street");

	protected ArrayList<Car> cars = new ArrayList<Car>();
	protected ArrayList<Bus> buses = new ArrayList<Bus>();
	protected ArrayList<Truck> trucks = new ArrayList<Truck>();

	protected int carNumber = 0;
	protected int defVehicleWidth;

	protected Street street;

	public VehiclePool(Street street) {
		this.street = street;

	}

	@Override
	public void update(Observable o, Object arg) {

		removeAllofStreetVehicles();

		if (firstStreetpartIsFree()) {
			Vehicle vehicle = carBusOrTruck();
			Clock clock = (Clock) o;
			clock.addObserver(vehicle);
			addVehicleToList(vehicle);
			setChanged();
			notifyObservers(vehicle);
			clearChanged();
			
		}
		
		logger.info(street);
	}
	
	private boolean firstStreetpartIsFree() {
		for (int i = 0; i < 40; i++) {
			if (!street.getSAttribute(i).isFree()) {
				return false;
			}
		}
		
		return true;
	}
	
	private Vehicle carBusOrTruck(){
		Random random = new Random();
		int rv = random.nextInt(10);
		
		if (rv<1) {
			return new Bus(this.street, 70, 0, 0);
		}else if (rv<3) {
			return new Truck(this.street, 70, 0, 0);
		}
		return new Car(this.street, 70, 0, 0);
	}

	private void removeAllofStreetVehicles(){
		Car gone = null;
		for (Car c : cars) {
			if (!c.isOnStreet()) {
				gone = c;
			}
		}
		cars.remove(gone);
		Bus bgone = null;
		for (Bus b : buses) {
			if (!b.isOnStreet()) {
				bgone = b;
			}
		}
		buses.remove(bgone);
		Truck tgone = null;
		for (Truck t : trucks) {
			if (!t.isOnStreet()) {
				tgone = t;
			}
		}
		trucks.remove(tgone);
	}

	public boolean firstStreetElementfree() {
		return street.getSAttribute(0).isFree();
	}

	@Override
	public void putVehicleOnStreet(Vehicle vehicle) {

		this.addVehicleToList(vehicle);
	}

	private void addVehicleToList(Vehicle vehicle) {
		if (Car.class.isInstance(vehicle)) {
			cars.add((Car) vehicle);
		}
		if (Bus.class.isInstance(vehicle)) {
			buses.add((Bus) vehicle);
		}
		if (Truck.class.isInstance(vehicle)) {
			trucks.add((Truck) vehicle);
		}
	}

	@Override
	public ArrayList<Car> getAllCars() {
		return this.cars;
	}

	@Override
	public ArrayList<Bus> getAllBuses() {
		return this.buses;
	}

	@Override
	public ArrayList<Truck> getAllTrucks() {
		return this.trucks;
	}

	@Override
	public int getAverageSpeedofCars() {
		int totalspeed = 0;
		for (Car c : cars) {
			totalspeed+=c.getSpeedinKM();
		}
		if (cars.size()!=0) {
			return totalspeed/cars.size();			
		}else {
			return 0;
		}
	}

	@Override
	public int getAverageSpeedofBuses() {
		int totalspeed = 0;
		for (Bus b : buses) {
			totalspeed+=b.getSpeedinKM();
		}
		if (buses.size()!=0) {
			return totalspeed/buses.size();
		}else {
			return 0;
		}
	}

	@Override
	public int getAverageSpeedofTrucks() {
		int totalspeed = 0;
		for (Truck t : trucks) {
			totalspeed+=t.getSpeedinKM();
		}
		if (trucks.size()!=0) {
			return totalspeed/trucks.size();
		}else {
			return 0;
		}
	}

	
}
